<?php
/**
 * Created by PhpStorm.
 * User: LiBing
 * Date: 2017/11/10
 * Time: 11:33
 * 麻将玩家的代理，封装了玩家麻将游戏的相关信息，同时负责返回给前台
 */

    require_once "MaJongLogic.php";
    class MaJongPlayer{
        //麻将玩家的UID
        public $playerUID;
        //玩家的手牌
        public $playerPai = array();
        //玩家的碰的牌
        public $playerPeng = array();
        //玩家的杠的牌
        public $playerGang = array();
        //玩家打的牌
        public $playerChuPai = array();

        //玩家准备的状态
        public $isReady = false;

        //玩家牌的当前可能性
        public $canGang = false;
        public $canFu = false;
        public $canPeng = false;

        //玩家当前的状态
        public $isTui = false;  //是否推牌
        public $isHu = false;

        //用于判断麻将逻辑的对象
        private $majangLogic;

        //玩家本局可听牌组合，array  (i=>array(打的什么牌, array(a, b, c)具体胡的牌)
        public $playerCurTing = array();
        //玩家实际推的牌
        public $playerTuiPai = array();

        //玩家加的底倍数
        public $diBei=0;
        //玩家赢的总分数
        public $winIntegral=0;
        public $que=0;//玩家缺的牌  0、1、2、3 无/筒/条/万
        public $baoJiao=false;
        public $paiNum=0;//辅助记录手牌数量

        public $daiRoom=array();

        public $huType=false;

        public $roomId=0;

        function __construct($playerUID)
        {
            $this->playerUID = $playerUID;
            $this->majangLogic = new MaJongLogic();
        }

        /**
         * 重置玩家的maJongPlayer属性
         */
        function resetPlayer(){
            $this->playerPai=array();
            $this->playerPeng=array();
            $this->playerGang=array();
            $this->playerChuPai=array();
            $this->isReady=false;
            $this->canGang=false;
            $this->canFu=false;
            $this->canPeng=false;
            $this->isTui=false;
            $this->isHu=false;
            $this->playerCurTing=array();
            $this->playerTuiPai=array();
            $this->diBei=0;
            $this->winIntegral=0;
            $this->que=0;
            $this->baoJiao=false;
            $this->huType=false;
            $this->roomId=0;
        }


        function isPlayerHu(){
            return $this->isHu;
        }

        function readyForPlay(){
            $this->isReady = true;
        }

        function isPlayerReady(){
            return $this->isReady;
        }

        /**
         * 获取玩家手牌的函数
         * @return array
         */
        function getPai(){
            return $this->playerPai;
        }

        /**
         * 获取玩家所有牌的函数，
         * @return array （0=》手牌，1=》碰的牌， 2=》杠的牌)
         */
        function getAllPai(){
            return array($this->playerPai, $this->playerPeng, $this->playerGang);
        }


        /**
         * 摸牌函数
         * @param $pai 就是一个整数
         * @param $playerID 摸牌人的UID
         * @param $roomType 房间类型 1西昌麻将 2成都麻将
         * @return array('hu'=>true/false, 'gang'=> array('ming'=>pai/false, 'an'=>array()), 'qianggang'=>false/playerID,
         * 'ting'=>array(i=>array(打什么牌, array(胡的牌)))
         */
        function moPai($playerID,$pai,$roomType){

            $returnArray = array();
            $returnArray['pai'] = $pai;
            $returnArray['playerID'] = $playerID;//玩家对应的ID

            //检查摸牌以后能否杠，能否胡，能否听牌
            if($roomType==1){
                //检查用户是否摆牌
                if($this->isTuiPai()){
                    $returnArray['hu'] = $this->checkHu($pai);
                    $returnArray['ting'] = array();
                    $returnArray['gang'] = $this->checkMoPaiGang($pai);
                }else{
                    //此时玩家没有摆牌便检查此玩家是否爆叫
                    $returnArray['hu'] = $this->checkHu($pai);
                    $returnArray['ting'] = $this->checkTing($pai);
                    $returnArray['gang'] = $this->checkMoPaiGang($pai);
                }

            }else if($roomType==2){
                if($this->majangLogic->isQue(array($this->playerPai,$this->playerPeng,$this->playerGang))){
                    //起手缺了
                    //检测是否缺了
                    if($this->que==0){
                        //还没定缺
                        $returnArray['hu'] = array();
                        $returnArray['ting'] = array();
                        $returnArray['gang'] = array("an"=>array(),"ming"=>array());
                    }else{
                        if($this->queYi()){
                            //真的缺了
                            $returnArray['hu'] = $this->checkHu($pai);
                            $returnArray['ting'] = $this->checkTing($pai);
                            $returnArray['gang'] = $this->checkMoPaiGang($pai);
                        }else{
                            //没缺
                            $returnArray['hu'] = array();
                            $returnArray['ting'] = array();
                            $returnArray['gang'] = array("an"=>array(),"ming"=>array());
                        }
                    }
                }else{
                    $returnArray['hu']=array();
                    $returnArray['ting']=array();
                    $returnArray['gang']=array("an"=>array(),"ming"=>array());
                }

            }

            //将摸的牌放入玩家手牌
            array_push($this->playerPai, $pai);
            sort($this->playerPai);

            return $returnArray;
        }

        /**
         * 检查成都麻将缺的函数
         * @return int 1/0
         */
        function queYi(){
            for($i=0;$i<count($this->playerPai);$i++){
                if(((int)($this->playerPai[$i]/10))+1==$this->que){
                    return false;
                }
            }
            return true;
        }

        /**
         * 打牌函数
         * @param $pai,一个来自前端的数据，就是一个数值
         * @return $tempCard 打出去的具体牌，用于计算结果
         */
        function daPai($pai){
            if(!$this->checkPai($pai)){
                return false;
            }
            //array_push($this->playerChuPai, $pai);
            for($i = 0; $i < count($this->playerPai); $i++){
                if($this->playerPai[$i] == $pai){
                    //打某张牌
                    array_splice($this->playerPai, $i, 1);
                    //记录该牌
                    array_push($this->playerChuPai, $pai);
                    return true;
                }
            }
            return false;
        }

        /**
         * 检查打牌是否合法的函数
         * @param $pai
         * @return bool
         */
        private function checkPai($pai){
            //  print_r($this->playerPai);
            for($i = 0; $i < count($this->playerPai); $i++){
                if($this->playerPai[$i] == $pai){
                    return true;
                }
            }
            return false;
        }

        /**
         * @param $pai 某个玩家打的牌
         * @return 如果能碰，返回true, 否则返回false
         */
        function checkPeng($pai){
            return  $this->majangLogic->checkPeng($this->playerPai, $pai);
        }

        /**
         * 查叫
         * @param $roomType
         * @return array
         */
        function checkJiao($roomType){
            if($roomType==2){
                //成都麻将，看手牌是否只有两门或一门
                $t=$this->majangLogic->doCheckTingPai($this->playerPai);
                if(count($t)>0){
                    //判断
                    $tong=0;
                    $tiao=0;
                    $wan=0;
                    for($i=0;$i<count($this->playerPai);$i++){
                        if($this->playerPai[$i]>=1&&$this->playerPai[$i]<=9){
                            $tong++;
                        }
                        if($this->playerPai[$i]>=11&&$this->playerPai[$i]<=19){
                            $tiao++;
                        }
                        if($this->playerPai[$i]>=21&&$this->playerPai[$i]<=29){
                            $wan++;
                        }
                    }
                    if($tong>0&&$tiao>0&&$wan>0){
                        return array();
                    }else{
                        return $t;
                    }

                }else{
                    return $t;
                }
            }else{
                return $this->majangLogic->doCheckTingPai($this->playerPai);
            }
        }

        /**
         * 模拟查叫
         * @param $roomType
         * @return array
         */
        function moNiCheckJiao($paiArray,$roomType){
            if($roomType==2){
                //成都麻将，看手牌是否只有两门或一门
                $t=$this->majangLogic->doCheckTingPai($paiArray);
                if(count($t)>0){
                    //判断
                    $tong=0;
                    $tiao=0;
                    $wan=0;
                    for($i=0;$i<count($paiArray);$i++){
                        if($paiArray[$i]>=1&&$paiArray[$i]<=9){
                            $tong++;
                        }
                        if($paiArray[$i]>=11&&$paiArray[$i]<=19){
                            $tiao++;
                        }
                        if($paiArray[$i]>=21&&$paiArray[$i]<=29){
                            $wan++;
                        }
                    }
                    if($tong>0&&$tiao>0&&$wan>0){
                        return array();
                    }else{
                        return $t;
                    }

                }else{
                    return $t;
                }
            }else{
                return $this->majangLogic->doCheckTingPai($paiArray);
            }
        }

        /**
         * @param $pai 某个玩家摸的牌
         * @return array('an'=>array(pai, pai), 'ming'=>pai/false);
         */
        function checkMoPaiGang($pai){
            return $this->majangLogic->checkMoPaiGang($this->playerPai, $this->playerPeng, $pai);
        }

        /**
         * 检查玩家打牌杠的函数
         * @param $pai  某个玩家打的牌
         * @return bool true/false
         */
        function checkDaPaiGang($pai){
            return $this->majangLogic->checkDaPaiGang($this->playerPai, $pai);
        }


        /**
         * @param $pai 某个玩家打的牌
         * @return 如果能胡，返回的是
         */
        function checkHu($pai){
            return $this->majangLogic->checkHu($this->playerPai, $pai);
        }

        /**
         * 检查玩家是否可听牌的函数
         * @param $pai 某个玩家的摸的牌
         * @return array 返回的听牌结果,array  (i=>array(打的什么牌, array(a, b, c)具体胡的牌)
         */
        function checkTing($pai){
            $this->playerCurTing=array();
            $temp=$this->majangLogic->canTingPai($this->playerPai,$pai);
            for($i=0;$i<count($temp);$i++){
                $this->playerCurTing[$i]["tingPai"]=$temp[$i][0];
                $this->playerCurTing[$i]["huPai"]=$temp[$i][1];
            }
            return $this->playerCurTing;
        }

        function tuiPai(){
            $this->isTui = true;
        }

        /**
         * 玩家是否推牌的函数
         * @return bool
         */
        function isTuiPai(){
            return $this->isTui;
        }


        /**
         * 初始化玩家手牌的函数
         * @param $pai 来自发牌函数的牌
         */
        function setPai($pai){
            $this->playerPai = $pai;
            //排序
            sort($this->playerPai);
        }

        /**
         * 玩家碰牌的函数
         * @param $pai，牌
         * @return bool，返回true/false
         */
        function pengPai($pai){
            for($i = 0; $i < count($this->playerPai) - 1; $i++){
                if(($this->playerPai[$i] == $pai) && ($this->playerPai[$i+1] == $pai)){

                    array_splice($this->playerPai, $i, 2);
                    array_push($this->playerPeng, $pai);

                    $r = $this->checkTing('');
                    //print_r($r);
                    //print_r($this->playerPai);
                    return $r;
                }
            }
            return false;
        }

        /**
         * 杠牌函数
         * @param $pai 杠的牌
         * @return int 0:不能杠或者错误，1：暗杠， 2：明杠
         */
        function gangPai($pai){

            for($i = 0; $i < count($this->playerPai) - 2; $i++){
                //如果玩家某3张牌一样
                if(($this->playerPai[$i] == $pai) && ($this->playerPai[$i+1] == $pai) && ($this->playerPai[$i+2] == $pai)){
                    if($i+3<count($this->playerPai)){
                        if($this->playerPai[$i+3] == $this->playerPai[$i]){
                            //杠牌
                            array_splice($this->playerPai, $i, 4);

                        }else{
                            //杠牌
                            array_splice($this->playerPai, $i, 3);
                        }
                    }else{
                        //杠牌
                        array_splice($this->playerPai, $i, 3);
                    }
                    array_push($this->playerGang, $pai);
                    return AN_GANG;
                }
            }

            for($i = 0; $i < count($this->playerPeng); $i++){
                if($this->playerPeng[$i] == $pai){
                    //从手牌中删除杠牌
                    for($j=0;$j<count($this->playerPai);$j++){
                        if($this->playerPai[$j]==$pai){
                            array_splice($this->playerPai,$j,1);
                            break;
                        }
                    }

                    array_splice($this->playerPeng, $i, 1);
                    array_push($this->playerGang, $pai);
                    return MING_GANG;
                }
            }
            echo "test false";
            return 0;

        }

        /**
         * 玩家自摸胡函数
         * @param $pai 摸到的牌
         * @return array(QING_YI_SE=> 0/1, DUI_ZI_HU=>0/1, JIANG_DUI=>0/1, 'GOU'=>int, 'QUE'=>0/1, 'huType'=>ZI_MO)
         */
        function ziMoHu($pai){
            //自摸胡，由于是摸牌胡，直接返回数据即可
            $r = $this->majangLogic->getHuInfo($this->playerPai, $this->playerPeng, $this->playerGang,$pai);
            $r['huType'] = ZI_MO;
            $this->huType=true;
            $this->isHu = true;
            return $r;
        }

        /**
         * 玩家点炮胡的函数
         * @param $pai
         * @return array(QING_YI_SE=> 0/1, DUI_ZI_HU=>0/1, JIANG_DUI=>0/1, 'GOU'=>int, 'QUE'=>0/1, 'huType'=>DIAN_PAO)
         */
        function dianPaoHu($pai){
            //点炮胡，由于是别人打给本玩家胡牌的，所以需要把牌推入数组
            array_push($this->playerPai, $pai);
            sort($this->playerPai);

            $r =  $this->majangLogic->getHuInfo(
                $this->playerPai, $this->playerPeng, $this->playerGang,$pai
            );
            $r['huType'] = DIAN_PAO;
            $this->huType=false;
            $this->isHu = true;
            return $r;
        }

    }

?>